fix(rename): read and write source files as UTF-8 - #6761
Conversation
Greptile SummaryThis PR makes
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| reflex/utils/rename.py | Detects declared Python source encodings and reuses them for reading and writing during rename. |
| tests/units/test_prerequisites.py | Adds byte-level tests for UTF-8 under a cp1252 locale and Python source declared as cp1252. |
| news/6714.bugfix.md | Documents the cross-platform source-encoding fix. |
Reviews (4): Last reviewed commit: "test(rename): handle platform newlines" | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 657b04cfd5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Merging this PR will not alter performance
Comparing Footnotes
|
reflex rename reads every .py/.md file in the user's app with Path.read_text() and writes it back with Path.write_text(), neither of which passed encoding=. Both default to the platform locale encoding, which on Western Windows is cp1252 rather than UTF-8. UTF-8-authored source containing non-ASCII bytes (curly quotes, emoji, accented identifiers or docstrings) is therefore silently corrupted on a Western Windows locale, or aborts the rename partway with UnicodeDecodeError on a CJK codepage, leaving the tree in an inconsistent state. Pass encoding="utf-8" on both calls, matching path_ops.find_replace which already does this. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
|
fixed the windows ci failures in 4f7d658. the encoding assertions remain byte-exact while accounting for the platform newline emitted by the existing text-write behavior. focused tests, ruff, and pyright pass locally. @reflex-dev please take another look when ci completes. |
All Submissions:
Type of change
What and why
reflex rename <new_name>walks the user's app and rewrites imports and the appname in every
.pyand.mdfile. The read/modify/write inrename_imports_and_app_name(reflex/utils/rename.py) usedPath.read_text()andPath.write_text()with noencoding=argument, so bothdefault to the platform's locale encoding. On a Western Windows locale that is
cp1252, not UTF-8.The consequences on non-UTF-8 locales:
contains non-ASCII bytes (curly quotes in docstrings, accented identifiers or
string literals, emoji) is decoded as cp1252, rewritten, and written back as
cp1252, mangling the user's own source.
read_text()raisesUnicodeDecodeError,aborting the rename partway through the tree and leaving some files already
rewritten and others not, i.e. an inconsistent app.
On a POSIX UTF-8 locale it round-trips, so this is effectively Windows-specific.
The fix passes
encoding="utf-8"on both calls. This mirrors the repo's ownreflex/utils/path_ops.pyfind_replace, which already reads and writes the sameread/replace/write pattern with
encoding="utf-8";rename.pywas the outlier.Changes
reflex/utils/rename.py: addencoding="utf-8"to theread_text()andwrite_text()calls inrename_imports_and_app_name(+2 / -2).tests/units/test_prerequisites.py: add regression testtest_rename_imports_and_app_name_preserves_utf8, colocated with the existingrename tests. It simulates a cp1252 default (monkeypatching
Path.read_text/write_textso a missingencodingfalls back to cp1252, while an explicitencoding=still passes through), writes a UTF-8 file with realistic non-ASCIIcontent, runs the rename, and asserts the bytes are preserved exactly and the
rename still happened. The test fails before the fix (
UnicodeDecodeError) andpasses after.
news/<pr>.bugfix.md: towncrier changelog fragment.Changes To Core Features:
Locally (all green):
uv run pytest tests/units/test_prerequisites.py -k rename-> 6 passeduv run pytest tests/units/test_prerequisites.py tests/units/utils-> 677 passed, 4 skippeduv run ruff check .(changed files) -> All checks passeduv run ruff format --check .(changed files) -> already formatteduv run pyright reflex/utils/rename.py tests/units/test_prerequisites.py-> 0 errorsuv run towncrier check --compare-with origin/main-> fragment found